package file

import (
	"io"
	"lark/src/object"
	"os"
)

// 注册文件模块的内置函数
func Register(env *object.Environment) {
	env.Set("open", value.NewBuiltinFunction("open", openFile))
	env.Set("read", value.NewBuiltinFunction("read", readFile))
	env.Set("write", value.NewBuiltinFunction("write", writeFile))
	env.Set("close", value.NewBuiltinFunction("close", closeFile))
	env.Set("exists", value.NewBuiltinFunction("exists", fileExists))
	env.Set("remove", value.NewBuiltinFunction("remove", removeFile))
	env.Set("mkdir", value.NewBuiltinFunction("mkdir", createDirectory))
	env.Set("listdir", value.NewBuiltinFunction("listdir", listDirectory))
	newEnv := object.NewEnclosedEnvironment(env, "file")
	newEnv.Set("connect", object.Symbol{
		Name:  "connect",
		Value: connectDB,
	})
}

// 文件对象结构体
type FileObject struct {
	File *os.File
}

// 实现解释器的Value接口
func (f *FileObject) Type() value.ValueType { return value.FILE_OBJ }
func (f *FileObject) Inspect() string       { return "<file>" }

// 打开文件函数
func openFile(args ...value.Value) value.Value {
	if len(args) != 2 {
		return value.NewError("错误: open() 函数需要两个参数: 文件名和模式")
	}

	filename, ok := args[0].(*value.String)
	if !ok {
		return value.NewError("错误: 第一个参数必须是字符串类型")
	}

	mode, ok := args[1].(*value.String)
	if !ok {
		return value.NewError("错误: 第二个参数必须是字符串类型")
	}

	var flags int
	var perm os.FileMode = 0666

	switch mode.Value {
	case "r":
		flags = os.O_RDONLY
	case "w":
		flags = os.O_WRONLY | os.O_CREATE | os.O_TRUNC
	case "a":
		flags = os.O_WRONLY | os.O_CREATE | os.O_APPEND
	case "r+":
		flags = os.O_RDWR
	case "w+":
		flags = os.O_RDWR | os.O_CREATE | os.O_TRUNC
	case "a+":
		flags = os.O_RDWR | os.O_CREATE | os.O_APPEND
	default:
		return value.NewError("错误: 不支持的文件模式: " + mode.Value)
	}

	file, err := os.OpenFile(filename.Value, flags, perm)
	if err != nil {
		return value.NewError("错误: 无法打开文件: " + err.Error())
	}

	return &FileObject{File: file}
}

// 读取文件函数
func readFile(args ...value.Value) value.Value {
	if len(args) != 1 {
		return value.NewError("错误: read() 函数需要一个参数: 文件对象")
	}

	fileObj, ok := args[0].(*FileObject)
	if !ok {
		return value.NewError("错误: 参数必须是文件对象")
	}

	data, err := io.ReadAll(fileObj.File)
	if err != nil {
		return value.NewError("错误: 读取文件失败: " + err.Error())
	}

	return value.NewString(string(data))
}

// 其他文件操作函数实现...
